// perl_object.cpp - base class for perl interface objects

#include "PlPN.h"

/*
 * PerlObj
 */

PerlObj::PerlObj() {}

PerlObj::~PerlObj() {}

void PerlObj::CreatePerlObj(const char* classname, void* ptr) {
	m_perl_obj = create_perl_object(ptr, classname);
	SvREFCNT_inc(m_perl_obj);
}

SV* PerlObj::GetPerlObj() {
	return m_perl_obj;
}

void PerlObj::InUse(bool in_use) {
	m_in_use = in_use;
}

bool PerlObj::InUse() {
	return m_in_use;
}

/*
 * PerlSink
 */

PerlSink::PerlSink() {}

PerlSink::~PerlSink() {}

void PerlSink::AttachPerlSink(SV* sink) {
	m_perl_sinks.push_back(sink);
	SvREFCNT_inc(sink);
}

void PerlSink::DetachPerlSink(SV* sink) {
	int n = -1;

	// while we're in here, we'll clear out any expired sinks
	for (int i = 0; i < m_perl_sinks.size(); i++) {
		if (SvRV(m_perl_sinks[i]) == 0) {
			SvREFCNT_dec(m_perl_sinks[i]);
			m_perl_sinks.erase(m_perl_sinks.begin()+i);
		}
	}

	// now we'll check for our sink
	for (int i = 0; i < m_perl_sinks.size(); i++) {
		// do the Perl objects point to the same underlying value?
		if (SvRV(m_perl_sinks[i]) == SvRV(sink)) {
			n = i;
			break;
		}
	}
	if (n > -1) {
		SvREFCNT_dec(m_perl_sinks[n]);
		m_perl_sinks.erase(m_perl_sinks.begin()+n);
	}
}

void PerlSink::DetachAllPerlSinks() {
	while (m_perl_sinks.size() > 0) {
		SvREFCNT_dec(m_perl_sinks[0]);
		m_perl_sinks.erase(m_perl_sinks.begin());
	}
}

void PerlSink::ResetPerlDoc(SV* doc) {
	if (m_perl_doc != NULL && ! PL_dirty)
		SvREFCNT_dec(m_perl_doc);
	m_perl_doc = doc;
	SvREFCNT_inc(m_perl_doc);
}
